package jstart.exe;

import java.io.File;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.logging.Logger;

/**
 * @author zwz
 * Created on 2021-02-08
 */
public class StartLauncher extends DefaultLauncher {

    private static final Logger logger = Logger.getLogger(StartLauncher.class.getSimpleName());

    StartLauncher(LaunchContext context) {
        super(context);
    }

    @Override public void launch() throws ReflectiveOperationException {
        String appMainClassName = getAppMainClassName();
        logger.info("appMainClassName=" + appMainClassName);
        // add jars to classpath
        addAppLibs();
        runAppMain(appMainClassName);
    }

    private String getAppMainClassName() {
        String className = getProperty("app.mainClass", "");
        if (Kits.isVisibleString(className)) return className;
        throw new RuntimeException("启动主类(app.mainClass)无效！");
    }

    private void addAppLibs() {
        AppClassLoader classLoader = null;
        if (context.getClassLoader() instanceof AppClassLoader) {
            classLoader = (AppClassLoader) context.getClassLoader();
        }
        if (classLoader == null) {
            logger.warning("classLoader is null!!");
        } else {
            logger.info("classLoader=" + classLoader);
            String[] libs = getProperty("app.libDirs", "lib").split(";");
            Path basePath = context.getBootDir()
                                   .toPath();
            for (String lib : libs) {
                File file = basePath.resolve(lib)
                                    .toFile();
                logger.info("add file/dir: " + file.getAbsolutePath() + " to classpath.");
                classLoader.addFileOrDir(file);
            }
        }
    }

    private void runAppMain(String mainClassName) throws ReflectiveOperationException {
        logger.info("run class: " + mainClassName);
        Class<?> mainClass = context.getClassLoader()
                                    .loadClass(mainClassName);
        Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);
        String[] mainArgs = getProperty("app.mainArgs", "").split(" ");
        mainMethod.invoke(null, new Object[] { mainArgs });
    }
}
